// Category.cs
// 
// Copyright © 2009 FreeZzaph
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program.  If not, see <http://www.gnu.org/licenses/>.
//

using System;
using System.Collections.Generic;
using System.Text;
using System.Text.RegularExpressions;

namespace LibFreeZzaph
{
	/// <summary>
	/// <para>
	/// Identifies a category, typically this will be "Anal sex" or
	/// "Hentai" or "Pregnant" or "Asian"... you get the picture.</para>
	/// <para>The name should be short, must be all lowercase, contain no whitespace
	/// and no special characters. The method
	/// <see cref="LibFreeZzaph.FreeZzaphUtility.Prettify(System.String)" />
	/// is a convenience method that turns any string into a legal name.
	/// It should be sufficient to run the input text through that method
	/// for most cases.</para>
	/// <para>The description should be a more descriptive name for the category.
	/// Typically, this will be the non-prettified name of the category. If the
	/// name is "analsex" or "anal" then the description will most likely be
	/// "Anal sex".
	/// </para>
	/// <para>
	/// The filter is a regular expression that decides what file name extensions
	/// to download for this category. The category just provides URLs to web pages,
	/// which the main program downloads files off of using the filter that
	/// the category provides.
	/// </para>
	/// </summary>
	public abstract class Category
	{
		
		// Useful, default image and movie filters
		protected static readonly string imageFilter = "jpe?g?|jfif?|jif|gif|png";
		protected static readonly string movieFilter = "mpe?g?|avi|rm|wmv|mkv|mov|qt|divx|flv|mp4|ogm|ogv";
		
		private string name;
		private string description;
		private string filter;
	
		/// <summary>
		/// Initializes a new instance of the Category class with the given name,
		/// description and filter.
		/// </summary>
		/// <param name="name">
		/// The name of the Category. This name should be short, must be all
		/// lowercase, contain no whitespace and no special characters. Hyphens
		/// are allowed. A name that does not conform to these specifications
		/// will cause an ArgumentException to be thrown.
		/// </param>
		/// <param name="description">
		/// The description of the Category. Should be a more descriptive name
		/// for the category. Typically, this will be the same as the name, but
		/// without the restrictions on case, symbols and whitespace.
		/// For instance, if the name is "analsex" or "anal", then a decent
		/// value for the description is "Anal sex".
		/// </param>
		/// <param name="filter">
		/// The regular expression that represent file extensions that this
		/// category provides. The filter is only to contain the file
		/// extensions, for example "(tar.)?(g?z|bz2?)" to fetch archive types
		/// commonly used on Unix and Unix-like systems.
		/// </param>
		public Category(string name, string description, string filter)
		{
			// Make sure the provided name is valid. If it's not, throw an
			// exception.
			string validName = Regex.Replace(name, "[^-a-z0-9]", "");
			if (name != validName)
				throw new ArgumentException("'name' argument contains illegal characters. Use the FreeZzaphUtility.Prettify() method to sanitize the string before handing it to the constructor.");
			
			this.name = name;
			this.description = description;
			this.filter = filter;
		}
		
		/// <value>
		/// Gets the name of the category
		/// </value>
		public string Name
		{
			get
			{
				return name;
			}
		}
		
		/// <value>
		/// Gets the description of the category
		/// </value>
		public string Description
		{
			get
			{
				return description;
			}
		}
		
		/// <value>
		/// Gets the regular expression filter of the category
		/// </value>
		public string Filter
		{
			get
			{
				return filter;
			}
		}
		
		/// <summary>
		/// Returns an array of URLs for the given category.
		/// </summary>
		/// <param name="start">
		/// The location within the category to start fetching URLs, for those
		/// sites that keep their entire list of URLs forever. The value 0 will
		/// fetch the most recent entries, and higher values will progressively
		/// head towards older entries. For sites that only keep a limited amount
		/// of links available at any given time, this value can be ignored.
		/// </param>
		/// <param name="count">
		/// The amount of URLs to fetch. A value of -1 means to let the plug-in
		/// itself decide how many to fetch, which will typically be a reasonable
		/// default value. The plug-in <b>must</b> appropriately handle a value
		/// of -1.
		/// </param>
		/// <returns>
		/// An list of URLs fetched using the given parameters.
		/// </returns>
		public abstract IList<Uri> FetchUris(uint start, int count);
		
	}
}
